package com.zhoug.common3.adapters.recycler.dividers;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;

import com.zhoug.common3.utils.LogUtils;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

/**
 * recycler 网格布局分割线
 * Adapter的布局文件的根布局设置margin属性会导致分割线错了,只能使用padding代替
 */
public class GridItemDecoration extends RecyclerView.ItemDecoration {
    private static final String TAG = ">>>GridItemDecoration";
    private static final boolean DEBUG = false;

    private Drawable mDivider;
    private boolean drawLeft;
    private boolean drawRight;
    private boolean drawTop;
    private boolean drawBottom;

    private int mHorizonSpan;//水平间距 px
    private int mVerticalSpan;//垂直间距 px


    private GridItemDecoration(int horizonSpan, int verticalSpan, int color,
                               boolean drawLeft, boolean drawTop, boolean drawRight, boolean drawBottom) {
        this.mHorizonSpan = horizonSpan;
        this.mVerticalSpan = verticalSpan;
        mDivider = new ColorDrawable(color);
        this.drawLeft = drawLeft;
        this.drawTop = drawTop;
        this.drawRight = drawRight;
        this.drawBottom = drawBottom;
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        drawHorizontal(c, parent);
        drawVertical(c, parent);
    }

    private void drawHorizontal(Canvas c, RecyclerView parent) {
        int childCount = parent.getChildCount();
        int spanCount = getSpanCount(parent);
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            //画顶部边界线
            if (i < spanCount && drawTop) {
                int left = child.getLeft() - params.leftMargin;
                int right = child.getRight() + params.rightMargin;
                int top = child.getTop() + params.topMargin;
                int bottom = top + mHorizonSpan;
                if (DEBUG) {
                    if (DEBUG) {
                        LogUtils.d(TAG, "drawHorizontal:mHorizonSpan=" + mHorizonSpan);
                    }
                    LogUtils.d(TAG, "drawHorizontal:left=" + left + ",top=" + top + ",right=" + right + ",bottom=" + bottom);
                }
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }

            //最后一行底部横线不绘制
            if (isLastRaw(parent, i, spanCount, childCount) && !drawBottom) {
                continue;
            }
            //绘制底部
            int left = child.getLeft() - params.leftMargin;
            int right = child.getRight() + params.rightMargin;
            int top = child.getBottom() + params.bottomMargin;
            int bottom = top + mHorizonSpan;

            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }

    }

    private void drawVertical(Canvas c, RecyclerView parent) {
        int childCount = parent.getChildCount();
        int spanCount = getSpanCount(parent);
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            //画左边
            if (drawLeft && i % spanCount == 0) {
                int top = child.getTop() - params.topMargin;
                int bottom = child.getBottom() + params.bottomMargin + mHorizonSpan;
                int left = child.getLeft() - params.rightMargin;
                int right = left + mVerticalSpan;
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }

            //最右边的
            if ((parent.getChildViewHolder(child).getAdapterPosition() + 1) % spanCount == 0) {
                if(drawRight){
                    int top = child.getTop() - params.topMargin;
                    int bottom = child.getBottom() + params.bottomMargin + mHorizonSpan;
                    int right = child.getRight() + params.rightMargin;
                    int left = right - mVerticalSpan;
                    mDivider.setBounds(left, top, right, bottom);
                    mDivider.draw(c);

                }else{
                    continue;
                }
            }


            int top = child.getTop() - params.topMargin;
            int bottom = child.getBottom() + params.bottomMargin + mHorizonSpan;
            int left = child.getRight() + params.rightMargin;
            int right = left + mVerticalSpan;
//            //满足条件( 最后一行 && 不绘制 ) 将vertical多出的一部分去掉;
            if (!drawRight && i == childCount - 1) {
                right -= mVerticalSpan;
            }
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    /**
     * 计算偏移量
     */
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int spanCount = getSpanCount(parent);
        int childCount = parent.getAdapter().getItemCount();
        int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();

        if (itemPosition < 0) {
            return;
        }

        int column = itemPosition % spanCount;
        int bottom;

        int left = column * mVerticalSpan / spanCount;
        int right = mVerticalSpan - (column + 1) * mVerticalSpan / spanCount;

        if (isLastRaw(parent, itemPosition, spanCount, childCount)) {
            if (drawBottom) {
                bottom = mHorizonSpan;
            } else {
                bottom = 0;
            }
        } else {
            bottom = mHorizonSpan;
        }
        outRect.set(left, 0, right, bottom);
    }

    /**
     * 获取列数
     */
    private int getSpanCount(RecyclerView parent) {
        // 列数
        int mSpanCount = -1;
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            mSpanCount = ((GridLayoutManager) layoutManager).getSpanCount();
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            mSpanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
        }
        return mSpanCount;
    }

    /**
     * 是否最后一行
     *
     * @param parent     RecyclerView
     * @param pos        当前item的位置
     * @param spanCount  每行显示的item个数
     * @param childCount child个数
     */
    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            return getResult(pos, spanCount, childCount);
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int orientation = ((StaggeredGridLayoutManager) layoutManager).getOrientation();
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                // StaggeredGridLayoutManager 且纵向滚动
                return getResult(pos, spanCount, childCount);
            } else {
                // StaggeredGridLayoutManager 且横向滚动
                if ((pos + 1) % spanCount == 0) {
                    return true;
                }
            }
        }
        return false;
    }


    private boolean getResult(int pos, int spanCount, int childCount) {
        int remainCount = childCount % spanCount;//获取余数
        //如果正好最后一行完整;
        if (remainCount == 0) {
            if (pos >= childCount - spanCount) {
                return true; //最后一行全部不绘制;
            }
        } else {
            if (pos >= childCount - childCount % spanCount) {
                return true;
            }
        }
        return false;
    }

    /**
     * 使用Builder构造
     */
    public static class Builder {
        private Context mContext;
        private Resources mResources;
        private boolean drawLeft;
        private boolean drawRight;
        private boolean drawTop;
        private boolean drawBottom;
        private int mHorizonSpan;
        private int mVerticalSpan;
        private int mColor;

        public Builder(Context context) {
            mContext = context;
            mResources = context.getResources();
            drawBottom = true;
            mHorizonSpan = 0;
            mVerticalSpan = 0;
            mColor = Color.WHITE;
        }

        /**
         * 通过资源文件设置分隔线颜色
         */
        public Builder setColorResource(@ColorRes int resource) {
            setColor(ContextCompat.getColor(mContext, resource));
            return this;
        }

        /**
         * 设置颜色
         */
        public Builder setColor(@ColorInt int color) {
            mColor = color;
            return this;
        }


        /**
         * 通过px设置垂直间距
         */
        public Builder setVerticalSpan(float yPx) {
            this.mVerticalSpan = (int) (yPx + 0.5f);
            return this;
        }

        /**
         * 通过dp设置水平间距
         */
        public Builder setHorizontalSpan(int xPx) {
            this.mHorizonSpan = (int) (xPx + 0.5f);
            return this;
        }


        /**
         * 四周的边线是否显示
         * @param left 默认false
         * @param top 默认false
         * @param right 默认false
         * @param bottom 默认true
         * @return
         */
        public Builder setDrawBound(boolean left, boolean top, boolean right, boolean bottom) {
            drawLeft = left;
            drawTop = top;
            drawRight = right;
            drawBottom = bottom;
            return this;
        }

        public GridItemDecoration build() {
            return new GridItemDecoration(mHorizonSpan, mVerticalSpan, mColor, drawLeft, drawTop, drawRight, drawBottom);
        }
    }

}
